在 昨天 Day 17,我們看到如何透過 LangChain 的工具系統,把 API 真正接上來,讓 AI 不只是「回答」,而是能 實際完成任務。
不過,當工具越來越多,問題就來了:
這就是 MCP (Model Context Protocol) 的價值。
MCP 把「工具」抽象成一個標準化協議,讓模型可以透過統一的方式存取它們。換句話說,工具不再依賴某個框架,而是變成 獨立可重複使用的服務。
簡單來說,MCP 提供三件事:
簡單來說,MCP 就像 「USB 介面」:
工具就像滑鼠或鍵盤,MCP 提供了統一的插槽,任何相容的系統都能直接使用。
我們延續昨天的場景 —— 查詢維也納天氣。
不同的是,這次我們用 MCP 服務來封裝,讓工具能被 Claude Desktop 或 LangChain 共用。
圖:MCP 把工具獨立成一個服務,Claude Desktop 呼叫 MCP Tool,再由 MCP 串接 AccuWeather API,最後整合結果回覆使用者。
在開始前,我們需要先建立一個 MCP Server 專案。
這裡使用的是 uv —— 一個現代化的 Python 專案管理工具。
它本身內建了常見的功能:
pyproject.toml
與 lockfile這些功能都被整合在同一套流程裡,讓我們能更快、更輕量地建立乾淨的專案環境。
再加上 MCP 官方文件中也經常搭配 uv 作為範例,因此它是目前 相當推薦的選擇。
以下是初始化步驟:
# 建立一個新的專案目錄
uv init weather
cd weather
# 建立虛擬環境並啟用
uv venv
source .venv/bin/activate
# 安裝相依套件
uv add "mcp[cli]" requests
# 建立 MCP Server 的主程式檔案
touch weather_mcp_server.py
完成後,將下面的程式碼(weather_mcp_server.py
)存入專案中:
import os
import requests
from mcp.server.fastmcp import FastMCP
# 從環境變數讀取 AccuWeather API Key
API_KEY = os.getenv("ACCUWEATHER_API_KEY")
if not API_KEY:
raise ValueError("請先設定 ACCUWEATHER_API_KEY 環境變數")
# 建立 FastMCP Server
mcp = FastMCP("weather-mcp")
@mcp.tool()
def get_weather(city: str) -> dict:
"""查詢指定城市的即時天氣(使用 AccuWeather API)。
Args:
city: 城市名稱(例如:維也納、台北)
Returns:
天氣資料字典
"""
# Step 1. 找城市代碼
loc_url = "https://dataservice.accuweather.com/locations/v1/cities/search"
loc_params = {"apikey": API_KEY, "q": city, "language": "zh-tw"}
loc_res = requests.get(loc_url, params=loc_params, timeout=10).json()
if not loc_res:
return {"error": f"找不到城市:{city}"}
location_key = loc_res[0]["Key"]
# Step 2. 查天氣
weather_url = f"https://dataservice.accuweather.com/currentconditions/v1/{location_key}"
weather_params = {"apikey": API_KEY, "language": "zh-tw", "details": "true"}
weather_res = requests.get(weather_url, params=weather_params, timeout=10).json()
return weather_res[0] if weather_res else {"error": "查不到天氣"}
if __name__ == "__main__":
mcp.run()
在 Claude Desktop 的 Settings → Developer → Edit Config
進行 MCP 設定
編輯 claude_desktop_config.json
:
{
"mcpServers": {
"accuweather": {
"command": "uv",
"args": [
"--directory",
"{MCP 程式路徑}",
"run",
"weather_mcp_server.py"
],
"env": {
"ACCUWEATHER_API_KEY": "{你的 API Key}"
}
}
}
這裡每個欄位的意義是:
mcpServers
一個 JSON 物件,裡面可以列出多個 MCP 服務。accuweather
是自訂的名稱(你也可以取成 weather
或其他名字),Claude 會依照這個名稱來識別 MCP Tool。
command
啟動 MCP Server 的指令。
這裡設定為 uv
,代表我們用 uv
來執行 Python 程式。
args
傳給 command
的參數。
--directory MCP 程式路徑
:指定 MCP server 的所在資料夾run weather_mcp_server.py
:要執行的檔案這樣 Claude 就能知道要執行哪個 Python MCP server。
env
傳遞給 MCP server 的環境變數。
在這裡我們需要把 ACCUWEATHER_API_KEY
提供給伺服器,否則工具無法呼叫 API。
這樣設定好之後,Claude Desktop 啟動時會自動依照這個配置去 開啟一個 MCP Server,讓 Claude 在需要時呼叫裡面的工具(例如 get_weather
)。
重新啟動 Claude Desktop,直接輸入:
維也納的天氣如何?
Claude 會自動呼叫 get_weather(city="維也納")
,並回覆最新的即時天氣。
圖:Claude Desktop 透過 MCP Tool 呼叫 get_weather(city="維也納"),並自動將 AccuWeather API 回傳的數據整理成自然語言回答。
在這個執行結果中,我們可以看到:
get_weather
工具,並傳入參數 city="維也納"
。這樣的設計讓工具不只是一段程式碼,而是成為 可跨應用共享的服務。不管是在 Claude Desktop、LangChain,甚至 VSCode 插件裡,都能以相同方式呼叫並取得結果。
今天我們看到 MCP (Model Context Protocol) 的價值:
透過「維也納天氣查詢」這個例子,我們看到 MCP 如何讓工具從「框架內的 Tools」升級成「跨應用的服務」。
明天,我們將進一步把 MCP 與 LangChain 結合,示範如何在 Agent 流程中直接呼叫 MCP 工具 —— 讓工具不只是獨立的服務,而能真正融入 跨平台、多工具的智慧助理。
圖:布拉格查理大橋(Charles Bridge)上的鍍金浮雕與祈願鐵欄。人們在此掛上象徵心願的鎖頭,將不同的故事匯聚於同一座橋。這正如 MCP 的角色 —— 為各種工具建立共通的「橋樑」,讓它們能跨越框架與系統,讓不同的系統都能連結其上,共同運作,展現跨越邊界的力量。(攝影:作者自攝)